package com.ruoyi.project.system.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ImageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Anonymous;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.interceptor.annotation.RepeatSubmit;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.system.domain.SiyuBaseinfo;
import com.ruoyi.project.system.domain.SiyuQuery;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.domain.dto.FacialVerification;
import com.ruoyi.project.system.domain.vo.UserQueryVo;
import com.ruoyi.project.system.mapper.SiyuBaseinfoMapper;
import com.ruoyi.project.system.mapper.SiyuQueryMapper;
import com.ruoyi.project.system.service.ISiyuQueryService;
import com.ruoyi.project.system.service.TencentService;
import com.tencentcloudapi.faceid.v20180301.models.CheckIdCardInformationResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 进件记录Controller
 */
@RestController
@RequestMapping("/system/query")
public class SiyuQueryController extends BaseController {

    @Autowired
    private ISiyuQueryService siyuQueryService;

    @Autowired
    private TencentService tencentService;

    @Autowired
    private SiyuQueryMapper siyuQueryMapper;

    @Autowired
    private SiyuBaseinfoMapper siyuBaseinfoMapper;

    @PreAuthorize("@ss.hasPermi('system:query:query')")
    @Anonymous
    @GetMapping("/data")
    public AjaxResult data(Integer queryId, Integer productId) {
        SiyuQuery siyuQuery = siyuQueryService.selectSiyuQueryByQueryId(queryId);
        siyuQuery.setProductId(productId);
        return siyuQueryService.queryData(siyuQuery);
    }

    /**
     * 添加基础信息和扣费
     * @param ID
     * @param data
     * @return
     */
    @Anonymous
    @RepeatSubmit(interval = 10000)
    @GetMapping("/refer")
    public AjaxResult addRefer(Integer ID, String data) {
        // 查询订单
        SiyuQuery siyuQuery = siyuQueryService.selectSiyuQueryByQueryId(ID);
        siyuQuery.setProductId(1);
        // 判断扣费
        siyuQueryService.baseFee(siyuQuery, siyuQuery.getUserId().longValue());
        // 写入数据
        return toAjax(siyuQueryService.setQueryinfo(1, ID, data, DateUtils.getNowDate()));
    }

    /**
     * 进行人脸核验和扣费
     *
     * @param files
     * @param ID
     * @return
     * @throws IOException
     */
    @Anonymous
    @RepeatSubmit(interval = 10000)
    @PostMapping("/authImg")
    public AjaxResult addSave(@RequestParam("files") List<MultipartFile> files, @NotNull Integer ID) throws IOException {
        // 1. 扣费
        SiyuQuery siyuQuery = siyuQueryMapper.selectSiyuQueryByQueryId(ID);
        siyuQuery.setProductId(2);
        AsyncManager.me().execute(AsyncFactory.aysBaseFee(siyuQuery));
        // 2. 发起证照核验
        CheckIdCardInformationResponse imgAuthResp;
        try {
            imgAuthResp = tencentService.imgAuth(files.get(0).getBytes());
            imgAuthResp.setPortrait(null);
        } catch (Exception e) {
            e.printStackTrace();
            return success(e.getMessage()).put("status", 210);
        }
        // 3. 保存证照文件
        String filePath = RuoYiConfig.getUploadPath();
        String frontImg = FileUploadUtils.upload(filePath, files.get(0)).replace("/profile/upload", "");
        String backImg = FileUploadUtils.upload(filePath, files.get(1)).replace("/profile/upload", "");
        // 4. 写入路径
        SiyuBaseinfo baseinfo = siyuBaseinfoMapper.baseInfo(ID);
        if (baseinfo == null) {
            baseinfo = new SiyuBaseinfo(frontImg, backImg, JSON.toJSONString(imgAuthResp));
            siyuBaseinfoMapper.insertSiyuBaseinfo(baseinfo);
            siyuQueryService.setQueryinfo(2, ID, baseinfo.getId().toString(), DateUtils.getNowDate());
        } else {
            siyuBaseinfoMapper.updateIDCardImg(baseinfo.getId(), frontImg, backImg, JSON.toJSONString(imgAuthResp));
        }
        if ("Success".equals(imgAuthResp.getResult())) {
            if (imgAuthResp.getName().equals(siyuQuery.getName()) && imgAuthResp.getIdNum().equals(siyuQuery.getCardNo())) {
                // 5. 证件与输入三要素一致 发起人脸核验
                return success("证件与输入三要素一致").put("status", 200);
            } else {
                return success("证件与输入三要素不一致").put("status", 210);
            }
        }
        return success(imgAuthResp.getWarnings()).put("status", 210);
    }

    @GetMapping("/reportFee")
    public AjaxResult reportFee(Integer queryId, Integer productId) {
        SiyuQuery siyuQuery = siyuQueryService.selectSiyuQueryByQueryId(queryId);
        // 异步扣费
        siyuQuery.setProductId(productId);
        return siyuQueryService.fee(siyuQuery, SecurityUtils.getUserId());
    }

    /**
     * 查询记录
     */
    @PreAuthorize("@ss.hasPermi('system:query:query')")
    @GetMapping("/record")
    public AjaxResult record(Integer productId, Integer queryId) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        SiyuQuery query = siyuQueryService.selectSiyuQueryByQueryId(queryId);

        if (user.isAdmin() || user.getUserId().longValue() == query.getUserId()) {
            AjaxResult result = new AjaxResult();
            HashMap<String, Object> map = siyuQueryMapper.selectQueryinfo(productId, queryId);
            if (map != null && !map.isEmpty()) {
                result.putAll(map);
                result.replace("time", result.get("time").toString().replace("T", " "));
                return result;
            } else {
                return success("无记录");
            }
        } else {
            return error();
        }
    }

    @GetMapping("/baseInfo")
    public AjaxResult baseInfo(@NotNull Long queryId) {
        return success(siyuQueryMapper.authInfo(queryId));
    }

    @PreAuthorize("@ss.hasPermi('system:query:query')")
    @GetMapping("/immovab")
    public AjaxResult immovab(Integer queryId) {
        return siyuQueryService.immovablePropert(siyuQueryService.selectSiyuQueryByQueryId(queryId));
    }

    /**
     * 获取发起人脸核验链接
     *
     * @param ID
     * @return
     * @throws Exception
     */
    @Anonymous
    @GetMapping(value = "/faceAuth")
    public String faceAuth(@NotNull Integer ID) throws Exception {
        SiyuQuery query = siyuQueryMapper.selectSiyuQueryByQueryId(ID);
        return tencentService.sendIdentityInfoUserInfo(new FacialVerification(query));
    }

    /**
     * 获取人脸核验结果
     *
     * @param orderNo
     * @param ID
     * @throws Exception
     */
    @Anonymous
    @GetMapping(value = "/faceResult")
    public void faceResult(@NotBlank String orderNo, @NotNull Integer ID) throws Exception {
        SiyuBaseinfo baseinfo = siyuBaseinfoMapper.baseInfo(ID);
        if (StringUtils.isEmpty(baseinfo.getAuthImg()) || StringUtils.isEmpty(baseinfo.getBiologyAuth())) {
            JSONObject faceAuthJson = tencentService.getFaceAuthResult(orderNo);
            for (int i = 0; i < 3; i++) {
                if ("0".equals(faceAuthJson.getString("code")) && faceAuthJson.getJSONObject("result").containsKey("photo")) {
                    String fileName = orderNo + ".png";
                    ImageUtils.Base64ToImage(faceAuthJson.getJSONObject("result").getString("photo"), fileName);
                    faceAuthJson.getJSONObject("result").remove("photo");
                    siyuBaseinfoMapper.updateFaceResult(ID, "/faceAuth/" + fileName, faceAuthJson.toJSONString());
                    return;
                }
                Thread.sleep(1500);
                faceAuthJson = tencentService.getFaceAuthResult(orderNo);
            }
            siyuBaseinfoMapper.updateFaceResult(ID, null, faceAuthJson.toJSONString());
        }
    }

    /**
     * 获取证件照片
     *
     * @param filePath
     * @return
     * @throws IOException
     */
    @ResponseBody
    @Anonymous
    @GetMapping(value = "/getAuthImg", produces = MediaType.IMAGE_JPEG_VALUE)
    public byte[] getAuthImg(@NotBlank String filePath) throws IOException {
        String downloadPath = RuoYiConfig.getUploadPath() + filePath;
        File file = new File(downloadPath);
        FileInputStream inputStream = new FileInputStream(file);
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes, 0, inputStream.available());
        return bytes;
    }

    /**
     * 更新校验码
     */
    @GetMapping("/setAuthCode")
    public AjaxResult updateAuthCode(SiyuQuery siyuQuery) {
        String authCode = UUID.randomUUID().toString().substring(0, 8);
        siyuQuery.setAuthCode(authCode);
        siyuQueryService.updateSiyuQuery(siyuQuery);
        return success(authCode);
    }

    /**
     * 获取授权三要素
     */
    @Anonymous
    @GetMapping("/authKey/{id}")
    public String authKey(@PathVariable("id") Integer id) {
        Map<String, Object> stringMap = siyuQueryMapper.selectAuthKey(id);
        LocalDateTime create_time = (LocalDateTime) stringMap.get("create_time");
        return "<html lang=\"en\">\n" +
                "<head>\n" +
                "  <meta charset=\"UTF-8\">\n" +
                "  <style>\n" +
                "    .title {\n" +
                "      font-size: 18px;\n" +
                "      color: #323334;\n" +
                "      font-weight: 600;\n" +
                "      text-align: center;\n" +
                "      margin-bottom: 10px;\n" +
                "    }\n" +
                "\n" +
                "    .text {\n" +
                "      font-size: 14px;\n" +
                "      color: #323334;\n" +
                "      line-height: 26px;\n" +
                "      text-indent: 5em;\n" +
                "    }\n" +
                "\n" +
                "    .left {\n" +
                "      margin-left: 35%;\n" +
                "      text-justify: inter-ideograph;\n" +
                "    }\n" +
                "\n" +
                "    .xhx {\n" +
                "      text-decoration: underline;\n" +
                "    }\n" +
                "  </style>\n" +
                "  <title>授权书</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "<div style=\"margin: 15px;\">\n" +
                "  <p class=\"title\">个人信息授权书</p>\n" +
                "  <p class=\"text\">为了保障您的合法权益，您应当阅读并遵守本授权书，请您务必审慎阅读、充分理解授权书条款内容。</p>\n" +
                "  <p class=\"text\">一、本人同意并授权眉山星业信息科技有限公司将自己的姓名、手机号、身份证号传送给温州信语网络科技有限公司，\n" +
                "    目的是请温州信语网络科技有限公司帮助调取本人的综合信用探查、征信及其他我所授权展示的信息等，\n" +
                "    同意并授权温州信语网络科技有限公司及眉山星业信息科技有限公司可以向合法来源或本人直接收集、存储或分析本人的名字、手机号、身份证号及信用情况等信息，\n" +
                "    本人同意并授权温州信语网络科技有限公司可以将本人上述信息和分析结果传给眉山星业信息科技有限公司及合作伙伴。\n" +
                "  </p>\n" +
                "  <p class=\"text\">二、为便于向本人提供更加优质的服务和产品，本人授权贵司可以将上述信息在进行了非指向性和脱敏化处理后，分享给必要的合作伙伴，或进行其他商业用途。</p>\n" +
                "\n" +
                "  <p class=\"text\">授权人声明：</p>\n" +
                "\n" +
                "  <p class=\"text\">本授权书是本人向眉山星业信息科技有限公司 及温州信语网络科技有限公司做出的承诺，效力具有独立性，不因其他任何合同条款无效而无效。</p>\n" +
                "\n" +
                "  <p class=\"text\">以上授权期限为本人作出本授权承诺之日起至本人与眉山星业信息科技有限公司所有业务终结之日止。</p>\n" +
                "\n" +
                "  <p class=\"text left\">授权人：<span class=\"xhx\" id=\"name\">" + stringMap.get("name") + "</span></p>\n" +
                "  <p class=\"text left\">授权人身份证：\n" +
                "    <span class=\"xhx\" id=\"cardNo\">" + stringMap.get("card_no") + "</span></p>\n" +
                "  <p class=\"text left\">授权人手机号码：\n" +
                "    <span class=\"xhx\" id=\"tel\">" + stringMap.get("tel") + "</span>\n" +
                "  </p>\n" +
                "  <p class=\"text left\">\n" +
                "    <span id=\"date\">" + create_time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "</span>\n" +
                "  </p>\n" +
                "</div>\n" +
                "</body>\n" +
                "</html>";
    }

    /**
     * 快速查询列表
     */
    @PreAuthorize("@ss.hasPermi('system:query:list')")
    @GetMapping("/quickList")
    public TableDataInfo quickList(UserQueryVo userQueryVo) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (!user.isAdmin()) {
            userQueryVo.setUserId(user.getUserId().intValue());
        }
        startPage();
        List<UserQueryVo> list = siyuQueryMapper.subQueryList(userQueryVo);

        for (UserQueryVo queryVo : list) {
            if (StringUtils.isNotEmpty(queryVo.getName())) {
                queryVo.setName("**" + queryVo.getName().substring(1));
            }
            if (StringUtils.isNotEmpty(queryVo.getCardNo())) {
                queryVo.setCardNo("******" + queryVo.getCardNo().substring(6));
            }
            if (StringUtils.isNotEmpty(queryVo.getTel())) {
                queryVo.setTel("*******" + queryVo.getTel().substring(7));
            }
        }
        return getDataTable(list);
    }

    @PreAuthorize("@ss.hasPermi('system:query:list')")
    @GetMapping("/subListByParent")
    public TableDataInfo subListByParent(UserQueryVo userQueryVo) {
        userQueryVo.setParent(SecurityUtils.getUserId());
        startPage();
        List<UserQueryVo> list = siyuQueryMapper.subQueryList(userQueryVo);
        return getDataTable(list);
    }

    /**
     * 获取进件记录详细信息
     */
    @Anonymous
    @GetMapping(value = "/{queryId}")
    public AjaxResult getInfo(@PathVariable("queryId") Integer queryId) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        SiyuQuery query = siyuQueryService.selectSiyuQueryByQueryId(queryId);
        if (user.isAdmin() || user.getUserId().intValue() == query.getUserId()) {
            return success(query);
        } else {
            return error("非法操作");
        }
    }

    /**
     * 新增进件记录
     */
    @PostMapping
    @Anonymous
    public AjaxResult add(@RequestBody SiyuQuery siyuQuery) {
        if (siyuQuery.getUserId() == null) {
            siyuQuery.setUserId(SecurityUtils.getUserId().intValue());
        }
        siyuQuery.setAuthCode(UUID.randomUUID().toString().substring(0, 8));
        return toAjax(siyuQueryService.insertSiyuQuery(siyuQuery)).put("ID", siyuQuery.getQueryId());
    }

    /**
     * 修改进件记录
     */
    @PreAuthorize("@ss.hasPermi('system:query:edit')")
    @Log(title = "进件记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SiyuQuery siyuQuery) {
        return toAjax(siyuQueryService.updateSiyuQuery(siyuQuery));
    }

    /**
     * 删除进件记录
     */
    @PreAuthorize("@ss.hasPermi('system:query:remove')")
    @Log(title = "进件记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{queryIds}")
    public AjaxResult remove(@PathVariable Integer[] queryIds) {
        return toAjax(siyuQueryService.deleteSiyuQueryByQueryIds(queryIds));
    }
}
